#include "temp_id_generator.h"

#include <boost/asio.hpp>

#include "rpc_thread_manager.h"
#include "im/common/common.h"

namespace imserver {

extern boost::asio::io_service g_io_service;

using apache::thrift::concurrency::Runnable;

static const int64_t COUNTER_STEP = 500;

int64_t UpdateTempIdCounter(int64_t new_id) {
  if (new_id > 0) {
    TempIdGenerator::Instance().current_id(new_id);
    return 0;
  }
  return -1;
}

class DistCounterGetTask : public Runnable {
 public:
  DistCounterGetTask(base::DistributedCounter & dist_counter) : dist_counter_(dist_counter) {}
  virtual void run() {
    int64_t id = dist_counter_.GetAndInc(COUNTER_STEP);
    if (id % COUNTER_STEP > 5) {
      id = dist_counter_.GetAndInc(2 * COUNTER_STEP - id % COUNTER_STEP);
    }
    LOG_INFO("update id from dist counter=" << id);
    g_io_service.post(boost::bind(UpdateTempIdCounter, id));
  }
private:
  base::DistributedCounter & dist_counter_;
};

TempIdGenerator::TempIdGenerator() : dist_counter_("/im_temp_id") {
  current_id_ = dist_counter_.GetAndInc(COUNTER_STEP);
  LOG_INFO("init id from dist counter=" << current_id_);
} 

int64_t TempIdGenerator::Generate() {
  // current_id_ += (1 + rand() % 9);
  current_id_ += (1 + rand() % 2);

  if ((COUNTER_STEP - current_id_ % COUNTER_STEP) < 20) {
    LOG_INFO("DistCounterGetTask created " << COUNTER_STEP << " - " 
             << (current_id_ % COUNTER_STEP) << " = " << (COUNTER_STEP - current_id_ % COUNTER_STEP));
    GetThreadManager()->add(boost::shared_ptr<Runnable>(new DistCounterGetTask(dist_counter_)));
  }
  return IM_TEMP_ID_BASE + current_id_;
}

}


